package xm.components.spinner
{
	import flash.display.MovieClip;
	import flash.events.Event;
	
	import xm.core.XMSprite;
	import xm.events.SpinnerContainerEvent;
	import xm.events.SpinnerEvent;
	
	/**
	 * SpinnerContainer 전체 스피너들의 움직임이 끝났을 때. 
	 */	
	[Event(name="spinnerContainerComplete", type="xm.events.SpinnerContainerEvent")]
	
	/**
	 * <br> 클래스 설명 : </br>
	 * @author 김정환
	 */	
	public class SpinnerContainer extends XMSprite
	{
		
		//-----------------------------------------------------------------------------------
		// public vars
		//-----------------------------------------------------------------------------------
		
		
		/**
		 * 스핀이 움직이고 있는지 체크.
		 */		
		public var isSpinMove : Boolean = true;
		
		
		//-----------------------------------------------------------------------------------
		// protected / internal vars
		//-----------------------------------------------------------------------------------
		
		/**
		 * Spinner 객체 List 
		 */		
		protected var spinnerList : Array = [];
		
		
		//-----------------------------------------------------------------------------------
		// private vars
		//-----------------------------------------------------------------------------------
		
		private var _mark : MovieClip;
		private var _frame : MovieClip;
		
		private var _defaultBorderThickness : Number = 22;
		private var _defaultTopMargin : Number = 3; 
		
		//-----------------------------------------------------------------------------------
		// public functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * constructor 
		 */	
		public function SpinnerContainer( defaultDataPovider : Array = null )
		{
			super();
			
			if( defaultDataPovider != null )
			{
				// 기본적으로 스피너 하나는 가지고 있어야 하므로.
				createSpinner( defaultDataPovider, true );
			}
		}
		
		
		
		/**
		 * commitProperties
		 */		
		override public function commitProperties():void
		{
			super.commitProperties();
			
		}
		
		
		
		/**
		 * updateDisplayList
		 */		
		override public function updateDisplayList( enforce : Boolean = false ):void
		{
			super.updateDisplayList(enforce);
			
			var i : int, len : int, spinner : Spinner, spinnerWidth : Number;
			
			this.setChildIndex( _frame, this.numChildren-1 );
			this.setChildIndex( _mark, this.numChildren-1 );
			
			_frame.width = viewWidth;
			_frame.height = viewHeight;
			
			_mark.width = viewWidth;
			_mark.y = ( viewHeight - _mark.height )/2;
			
			
			i=0;
			len = spinnerList.length;
			spinnerWidth = (viewWidth-_defaultBorderThickness*2)/len;
			
			while( i<len )
			{
				spinner = spinnerList[ i ] as Spinner;
				
				spinner.x = i*spinnerWidth + _defaultBorderThickness;
				spinner.y = _defaultTopMargin;
				spinner.viewHeight = viewHeight-_defaultTopMargin;
				spinner.viewWidth = spinnerWidth;
				spinner.invalidateDisplayList();
				++i;
			}
		}
		
		
		/**
		 * 
		 * <br />
		 * @param index - index;
		 * @return Spinner
		 */		
		public function getSpinnerAt( index : int ):Spinner
		{
			return spinnerList[ index ] as Spinner;
		}
		
		/**
		 * 
		 * <br />
		 * @param spinner : Spinner
		 * @return : int
		 */		
		public function getSpinnerIndex( spinner : Spinner ):int
		{
			return spinnerList.indexOf( spinner );
		}
		
		/**
		 * 스피너의 인덱스를 변경하기.
		 * <br /><br />
		 * @param spinner
		 * @param index
		 */		
		public function setSpinnerIndex( spinner : Spinner, index : int ):void
		{
			var currentIndex : int = spinnerList.indexOf( spinner );
			spinnerList.splice( currentIndex, 1 );
			spinnerList[ index ] = spinner;
		}
		
		/**
		 * spinnerList 에서 해당 index의 Spinner 제거.
		 * @param index
		 */		
		public function removeSpinnerAt( index : int ):void
		{
			removeSpinner( spinnerList[ index ] as Spinner );
		}
		
		/**
		 * spinner 제거
		 * <br /><br />
		 * @param spinner
		 */		
		public function removeSpinner( spinner : Spinner ):void
		{
			var idx : int = spinnerList.indexOf( spinner );
			
			spinnerList.splice( idx, 1 );
			if( this.contains( spinner ) ) this.removeChild( spinner );
			spinner.removeEventListener(SpinnerEvent.SPINNER_UPDATE, onSpinnerUpdate );
			spinner.removeEventListener(SpinnerEvent.SPINNER_COMPLETE, onSpinnerComplete );
			
		}
		
		
		/**
		 * @param spinner
		 */		
		public function addSpinner( spinner : Spinner ):void
		{
			this.addSpinnerAt( spinner, spinnerList.length );
		}
		
		/**
		 * @param spinner
		 */		
		public function addSpinnerAt( spinner : Spinner, index : int ):void
		{
			this.spinnerList[ index ] = spinner;
			addChild( spinner );
			
			
			spinner.addEventListener(SpinnerEvent.SPINNER_UPDATE, onSpinnerUpdate );
			spinner.addEventListener(SpinnerEvent.SPINNER_COMPLETE, onSpinnerComplete );
		}
		
		
		/**
		 * spinner.invalidateDisplayList(); 가 자동으로 호출됨.
		 * <br /><br />
		 * @param dataProvider : Array - Spinner DataList 
		 * @param autoAdd : Boolean - 자동으로 addSpinner 호출여부
		 * @return Spinner
		 */		
		public function createSpinner( dataProvider : Array, autoAdd : Boolean = true ):Spinner
		{
			var spinner : Spinner;
			
			spinner = new Spinner();
			spinner.dataProvider = dataProvider;
			spinner.invalidateDisplayList();
			if( autoAdd ) addSpinner( spinner );
			
			return spinner;
		}
		
		
		//-----------------------------------------------------------------------------------
		// life cycle functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * createChildren
		 */		
		override public function createChildren():void
		{
			super.createChildren();
			
			_frame = new XM_DEFAULT_SKIN_PICKER_FRAME();
			addChild( _frame );
		
			_mark = new XM_DEFAULT_SKIN_PICKER_MARK();
			_mark.mouseChildren = false;
			_mark.mouseEnabled = false;
			addChild( _mark );
			
		}
		
		
		/**
		 * createComplete
		 */		
		override public function creationComplete():void
		{
			super.creationComplete();
			
		}
		
		
		/**
		 * add
		 */		
		override public function add():void
		{
			super.add();
		}
		
		
		/**
		 * remove
		 */		
		override public function remove():void
		{
			super.remove();
		}
		
		
		/**
		 * destroy
		 */		
		override public function destroy():void
		{
			var i:int, len:int;
			
			isSpinMove = false;
			
			
			// 리스트제거.
			i = 0;
			len = spinnerList.length;
			while( i<len )
			{
				( spinnerList[ i ] as Spinner ).removeEventListener(SpinnerEvent.SPINNER_UPDATE, onSpinnerUpdate );
				( spinnerList[ i ] as Spinner ).removeEventListener(SpinnerEvent.SPINNER_COMPLETE, onSpinnerComplete );
				( spinnerList[ i ] as Spinner ).destroy();
				delete spinnerList[ i ];
				++i;
			}
			spinnerList = null;
			
			
			
			// 자식제거
			if( _mark )
			{
				if( _mark.parent ) _mark.parent.removeChild( _mark );
				
				_mark = null;
			}
			
			if( _frame )
			{
				if( _frame.parent ) _frame.parent.removeChild( _frame );
				_frame = null;
			}
			
			_defaultBorderThickness = NaN;
			_defaultTopMargin = NaN;
			
			
			super.destroy();
		}
		
		
		/**
		 * spinnerList 복제배열 반환.
		 * <br />
		 * spinnerList는 외부에서 컨트롤할 수 없다.
		 * <br /> 
		 */		
		public function getSpinnerList():Array
		{
			return spinnerList.concat();
		}
		
		//-----------------------------------------------------------------------------------
		// setter / getter
		//-----------------------------------------------------------------------------------
		
		
		/**
		 * 선택 인덱스 배열 반환.
		 * <br /><br />
		 * @return Array
		 */		
		public function get selectedIndices():Array
		{
			var arr : Array = [],
				i : int = 0,
				len : int = spinnerList.length;
			
			while( i<len )
			{
				arr.push( ( spinnerList[ i ] as Spinner ).selectedIndex );
				++i;
			}
			
			return arr; 
		}
		
		
		/**
		 * 선택 데이터 배열 반환.
		 * <br /><br />
		 * @return Array
		 */		
		public function get selectedDatas():Array
		{
			var arr : Array = [],
				i : int = 0,
				len : int = spinnerList.length;
			
			while( i<len )
			{
				arr.push( ( spinnerList[ i ] as Spinner ).selectedData );
				++i;
			}
			
			return arr; 
		}
		
		
		
		//-----------------------------------------------------------------------------------
		// protected functions
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		// internal functions
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		// private functions
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		// event handler
		//-----------------------------------------------------------------------------------
		
		
		
		/**
		 * @param e
		 */		
		protected function onSpinnerComplete(e:SpinnerEvent):void
		{
			var i:int, len:int, spinner : Spinner, indices : Array, datas : Array;
			
			indices = [];
			datas = [];
			i=0;
			len=spinnerList.length;
			
			while( i<len )
			{
				spinner = spinnerList[ i ] as Spinner;
				if( spinner.isSpinMove == true ) return;
				
				indices.push( spinner.selectedIndex );
				datas.push( spinner.selectedData );
				0
				
				++i;
			}
			
			this.isSpinMove = false;
			
			var event : SpinnerContainerEvent = new SpinnerContainerEvent( SpinnerContainerEvent.SPINNER_CONTAINER_COMPLETE, false, false );
			event.currentDatas = datas;
			event.currentIndices = indices;
			
			dispatchEvent( event );
		}
		
		/**
		 * @param e
		 */		
		protected function onSpinnerUpdate(e:SpinnerEvent):void
		{
			this.isSpinMove = true;
		}		
		
		
		
		
		
	}
}